package clusterServer

import (
	"context"
	"devops-super/api"
	v1 "devops-super/api/clusters/v1"
	"devops-super/internal/consts"
	"devops-super/internal/dao"
	"devops-super/internal/model/entity"
	"devops-super/internal/model/mymodel"
	"devops-super/internal/service"
	"devops-super/utility/util/arrayUtil"
	"errors"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"

	"github.com/gogf/gf/v2/os/glog"
)

type sClusterServer struct{}

var cols = dao.AppClusterServer.Columns()

func init() {
	service.RegisterClusterServer(New())
}

func New() *sClusterServer {
	return &sClusterServer{}
}

// Add 添加集群服务器
func (*sClusterServer) Add(ctx context.Context, in *entity.AppClusterServer) (err error) {
	// 检查服务器名称是否已存在
	count, _ := dao.AppClusterServer.Ctx(ctx).Where(cols.Name, in.Name).Count()
	if count > 0 {
		return errors.New("server name already exists")
	}

	// 检查服务器唯一标识是否已存在
	count1, _ := dao.AppClusterServer.Ctx(ctx).Where(cols.ServerKey, in.ServerKey).Count()
	if count1 > 0 {
		return errors.New("serverKey already exists")
	}

	_, err = dao.AppClusterServer.Ctx(ctx).Insert(in)
	return
}

// Upt 更新集群服务器
func (*sClusterServer) Upt(ctx context.Context, in *entity.AppClusterServer) (err error) {
	// 检查服务器名称是否已存在（排除当前记录）
	count, _ := dao.AppClusterServer.Ctx(ctx).Where(cols.Name, in.Name).Where(cols.Id, "!=", in.Id).Count()
	if count > 0 {
		return errors.New("server name already exists")
	}

	// 检查服务器唯一标识是否已存在（排除当前记录）
	count1, _ := dao.AppClusterServer.Ctx(ctx).Where(cols.ServerKey, in.ServerKey).Where(cols.Id, "!=", in.Id).Count()
	if count1 > 0 {
		return errors.New("serverKey already exists")
	}

	_, err = dao.AppClusterServer.Ctx(ctx).WherePri(in.Id).OmitNilData().Data(in).Update()
	return
}

// GetPageLst 分页获取集群服务器列表
func (*sClusterServer) GetPageLst(ctx context.Context, in *api.PageLstReq) (out *api.PageLstRes[*mymodel.ClusterServerResponse], err error) {
	out = &api.PageLstRes[*mymodel.ClusterServerResponse]{}
	m := dao.AppClusterServer.Ctx(ctx).Safe(true)

	// 名称筛选
	if name := in.Wheres.Get("name"); !name.IsNil() {
		m = m.Where(cols.Name+" like ? ", "%"+name.String()+"%")
	}

	// 服务器标识筛选
	if serverKey := in.Wheres.Get("serverKey"); !serverKey.IsNil() {
		m = m.Where(cols.ServerKey+" like ? ", "%"+serverKey.String()+"%")
	}

	// 分页查询
	var entities []*entity.AppClusterServer
	if err = m.Offset(in.Offset()).Limit(in.Limit()).ScanAndCount(&entities, &out.Total, false); err != nil {
		return
	}
	// 映射到响应结构体
	out.List = make([]*mymodel.ClusterServerResponse, len(entities))
	for i, entity2 := range entities {
		response := &mymodel.ClusterServerResponse{}
		if err = gconv.Struct(entity2, response); err != nil {
			return
		}
		out.List[i] = response
	}
	return
}

// Del 删除集群服务器
func (*sClusterServer) Del(ctx context.Context, id int) (err error) {
	// 这里可以添加删除前的业务逻辑检查
	// 例如：检查该服务器是否有相关的集群数据或服务在运行
	_, err = dao.AppClusterServer.Ctx(ctx).WherePri(id).Delete()
	return
}

func (*sClusterServer) GetOne(ctx context.Context, id int) (out *entity.AppClusterServer, err error) {
	out = &entity.AppClusterServer{}
	err = dao.AppClusterServer.Ctx(ctx).WherePri(id).Scan(&out)
	return
}

func (*sClusterServer) GetOptions(ctx context.Context, in *v1.ClusterServerGetOptionsReq) (out *v1.ClusterServerGetOptionsRes, err error) {
	out = new(v1.ClusterServerGetOptionsRes)
	var data []*entity.AppClusterServer
	err = dao.AppClusterServer.Ctx(ctx).Scan(&data)
	if err != nil {
		glog.Line().Error(ctx, err)
		return
	}
	out.Options = make([]*api.FormOptionsItem, 0)
	if data != nil {
		for _, v := range data {
			out.Options = append(out.Options, &api.FormOptionsItem{
				Value: v.Id,
				Label: v.Name,
			})
		}
	}

	return
}

// GetClusterKeys 从env配置里读取options
func (*sClusterServer) GetClusterKeys(ctx context.Context, in *v1.ClusterServerGetClusterKeysReq) (out *v1.ClusterServerGetClusterKeysRes, err error) {
	out = &v1.ClusterServerGetClusterKeysRes{}
	out.Options = make([]*api.FormOptionsItem, 0)
	confKey := consts.EnvConfig_Clusters + "." + in.Type
	confString, err := g.Cfg().Get(ctx, confKey)
	if err != nil {
		return
	}
	var conf []*mymodel.ClusterKeyItem
	err = gconv.Structs(confString, &conf)
	if err != nil {
		return
	}
	if len(conf) == 0 {
		return nil, errors.New("no configs")
	}
	var deptServers []*entity.AppDeptToServerRecord
	cols1 := dao.AppDeptToServerRecord.Columns()
	err = dao.AppDeptToServerRecord.Ctx(ctx).Where(cols1.Type, in.Type).Scan(&deptServers)
	if err != nil {
		glog.Line().Error(ctx, err)
		return
	}
	keys := make([]string, 0)
	for _, server := range deptServers {
		keys = append(keys, server.ServerKey)
	}
	for _, v := range conf {
		// 没被占用
		if !arrayUtil.IsExistsItem(v.Name, keys) {
			out.Options = append(out.Options, &api.FormOptionsItem{
				Value: v.Name,
				Label: v.Name + "（Free）",
			})
		} else { //已被占用
			out.Options = append(out.Options, &api.FormOptionsItem{
				Value: v.Name,
				Label: v.Name + "（In Use）",
			})
		}
	}
	return
}
